///////////////////////////////////////////////////////////////
// Copyright(c) BeingStudio
// 
// FileName : ProgrammingPearls-01-01
// Creator  : ChenShiCai
// E-Mail   : BeingStudio@GMail.com
// Date     : 2008-05-18
// Comment  : 
//
///////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

#include <errno.h>

#include "ProgrammingPearls-01-01.h"

#define USING_BITMAP
#define LINE_LENGTH 1024

int ReportResult(int nNum) 
{
	int nResult = false;    
	int nRetCode = false;

	printf("%d\t", nNum);

	nResult = true;
//Exit0:
	return nResult;
}

#ifdef USING_SET

#include <set>

int SortFile(char szFileName[]) 
{
	int nResult = false;    
	int nRetCode = false;

    FILE *pFile = NULL;
    char  ReadLine[LINE_LENGTH];
    char *pRetCode = NULL;
    int   nReadNum = 0;
   
    std::set<int> Sort_Set;
    std::set<int>::iterator Itor, EndItor;
    std::pair<std::set<int>::iterator, bool> SetRetCode;

    PROCESS_ERROR(szFileName);

    pFile = fopen(szFileName, "r");
    PROCESS_ERROR(pFile);

    while (true)
    {
        pRetCode = fgets(ReadLine, sizeof(ReadLine), pFile);
        if (!pRetCode)
        {
            nRetCode = feof(pFile);
            if(nRetCode)
                break;

            if (errno == EINVAL)
                continue;
            goto Exit0;
        }
        ReadLine[sizeof(ReadLine) - 1] = '\0';

        errno = 0;
        nReadNum = atoi(ReadLine);
        PROCESS_ERROR(errno == 0);

        SetRetCode = Sort_Set.insert(nReadNum);
        PROCESS_ERROR(SetRetCode.second);	        
    }

	for (Itor = Sort_Set.begin(), EndItor = Sort_Set.end(); Itor != EndItor; ++Itor)
	{
        nRetCode = ReportResult(*Itor);
        PROCESS_ERROR(nRetCode);
	}

    nResult = true;
Exit0:
    Sort_Set.clear();
    fclose(pFile);
	return nResult;
}

#endif//USING_SET

#ifdef USING_SORT

#define SORT_ERRER_NO 88
#define ARRAY_LENGTH (16 * 1024 * 1024)

int Compare(const void *Left, const void *Right)
{
    int nResult = false;    
    int nRetCode = false;

    nRetCode = (*(int *)Left) - (*(int *)Right);
    if (!nRetCode)
        errno = SORT_ERRER_NO;

    nResult = nRetCode;
//Exit0:
    return nResult;
}

int SortFile(char szFileName[])
{
    int nResult = false;    
    int nRetCode = false;

    FILE *pFile = NULL;
    char  ReadLine[LINE_LENGTH];
    char *pRetCode = NULL;
    int   nReadNum = 0;

    int *pnSortArray = NULL;
    int nArrayCount = 0;

    PROCESS_ERROR(szFileName);    

    pnSortArray = new int[ARRAY_LENGTH];
    PROCESS_ERROR(pnSortArray);

    pFile = fopen(szFileName, "r");
    PROCESS_ERROR(pFile);

    while (true)
    {
        pRetCode = fgets(ReadLine, sizeof(ReadLine), pFile);
        if (!pRetCode)
        {
            nRetCode = feof(pFile);
            if(nRetCode)
                break;

            if (errno == EINVAL)
                continue;
            goto Exit0;
        }
        ReadLine[sizeof(ReadLine) - 1] = '\0';

        errno = 0;
        nReadNum = atoi(ReadLine);        
        PROCESS_ERROR(errno == 0);

        if (nArrayCount < ARRAY_LENGTH)
        {
            pnSortArray[nArrayCount++] = nReadNum;
        }
        else
        {
            break;
        }
    }

    errno = 0;
    qsort(pnSortArray, nArrayCount, sizeof(int), Compare);
    PROCESS_ERROR(errno == 0);

    for (int i = 0; i < nArrayCount; ++i)
    {
        nRetCode = ReportResult(pnSortArray[i]);
        PROCESS_ERROR(nRetCode);
    }

    nResult = true;
Exit0:
    SAFE_DELETE_ARRAY(pnSortArray);
    fclose(pFile);
    return nResult;
}

#endif//USING_SORT

#ifdef USING_BITMAP

#include <memory.h>
#define BITMAP_LENGTH (2 * 1024 * 1024)
//#define BITMAP_LENGTH (0xffffffff / 8)

int SortFile(char szFileName[])
{
    int nResult = false;    
    int nRetCode = false;

    FILE *pFile = NULL;
    char  ReadLine[LINE_LENGTH];
    char *pRetCode = NULL;
    int   nReadNum = 0;

    unsigned char *pbyBitMap = NULL;

    PROCESS_ERROR(szFileName);

    pbyBitMap = new unsigned char[BITMAP_LENGTH];
	PROCESS_ERROR(pbyBitMap);
    memset(pbyBitMap, 0, BITMAP_LENGTH);


    pFile = fopen(szFileName, "r");
    PROCESS_ERROR(pFile);

    while (true)
    {
        pRetCode = fgets(ReadLine, sizeof(ReadLine), pFile);
        if (!pRetCode)
        {
            nRetCode = feof(pFile);
            if(nRetCode)
                break;

            if (errno == EINVAL)
                continue;
            goto Exit0;
        }
        ReadLine[sizeof(ReadLine) - 1] = '\0';

        errno = 0;
        nReadNum = atoi(ReadLine);        
        PROCESS_ERROR(errno == 0);

		PROCESS_ERROR(nReadNum < BITMAP_LENGTH);

        if (pbyBitMap[nReadNum >> 3] & (1 << (nReadNum & 7)))
            goto Exit0;
           
        pbyBitMap[nReadNum >> 3] |= (1 << (nReadNum & 7));
        //pBitMap[nReadNum / 8] |= (1 << (nReadNum % 8));
    }

    for (int i = 0; i <BITMAP_LENGTH << 3; ++i)
    {
        if (!(pbyBitMap[i >> 3] & (1 << (i & 7))))
            continue;

        nRetCode = ReportResult(i);
        PROCESS_ERROR(nRetCode);
    }  

    nResult = true;
Exit0:
    SAFE_DELETE_ARRAY(pbyBitMap);
    fclose(pFile);
    return nResult;
}


#endif//USING_BITMAP

